package cn.lili.common.extend;

import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;

/**
 * 扩展模型工具类，
 * 用于将枚举字段 转换原始模型中扩展字段的映射
 *
 * @author liushuai(liushuai711 @ gmail.com)
 * @version v4.0
 * @Description:
 * @since 2023/2/10 15:34
 */
@Slf4j
public class ExtendEntityUtils {


    /**
     * 重写对象
     * 将扩展后的对象重写为基础模型对象并返回
     *
     * @param pluginEntity 扩展后的对象
     * @return 原始模型
     */
    public static Object rewrite(Object pluginEntity) {

        try {

            ExtendClass extendClass = pluginEntity.getClass().getAnnotation(ExtendClass.class);
            if (extendClass == null) {
                throw new ServiceException("未使用@ExtendClass 导致无法识别转换后的模型");
            }

            Class originalEntity = Class.forName(extendClass.getClass().getTypeName());

            Field[] originalFields = originalEntity.getClass().getDeclaredFields();
            Field[] pluginFields = pluginEntity.getClass().getDeclaredFields();
            //原始对象初始赋值给转换后的对象
            BeanUtil.copyProperties(pluginEntity, originalEntity);


            //源头对象字段
            for (Field pluginField : pluginFields) {
                //获取扩展字段注解
                ExtendField extendField = pluginField.getAnnotation(ExtendField.class);
                //判定注解有效性
                if (extendField == null) {
                    continue;
                }

                //循环基础模型对象字段
                for (Field originalField : originalFields) {
                    if (originalField.getName().equals(extendField.value().name())) {
                        //处理转换关系，确认写入对象和写入数据来源
                        writeField(pluginField, pluginEntity, originalField, originalEntity);
                    }
                }
            }
        } catch (Exception e) {
            log.error("自定义转换器反射转换异常", e);

        }
        return pluginEntity;
    }

    /**
     * 基础模型字段自动转化扩展模型
     *
     * @param originalEntity 基础应用模型
     * @param pluginEntity   扩展引用模型
     */
    public static Object convert(Object originalEntity, Object pluginEntity) {

        try {
            Field[] originalFields = originalEntity.getClass().getDeclaredFields();
            Field[] pluginFields = pluginEntity.getClass().getDeclaredFields();
            //原始对象初始赋值给转换后的对象
            BeanUtil.copyProperties(originalEntity, pluginEntity);


            //源头对象字段
            for (Field pluginField : pluginFields) {
                //获取扩展字段注解
                ExtendField extendField = pluginField.getAnnotation(ExtendField.class);
                //判定注解有效性
                if (extendField == null) {
                    continue;
                }

                //循环基础模型对象字段
                for (Field originalField : originalFields) {
                    if (originalField.getName().equals(extendField.value().name())) {
                        //处理转换关系，确认写入对象和写入数据来源
                        writeField(originalField, originalEntity, pluginField, pluginEntity);
                    }
                }
            }
        } catch (Exception e) {
            log.error("自定义转换器反射转换异常", e);

        }
        return pluginEntity;
    }

    /**
     * 将指定字段值写入到期望写入的字段
     *
     * @param fromField 来源字段
     * @param fromObj   来源对象
     * @param toField   写入字段
     * @param toObj     写入对象
     */
    private static void writeField(Field fromField, Object fromObj, Field toField, Object toObj) {

        try {
            fromField.setAccessible(true);
            Object result = fromField.get(fromObj);
            //参数不为空则进行赋值
            if ((result != null) && StringUtils.isNotEmpty(result.toString())) {
                toField.setAccessible(true);
                toField.set(toObj, result.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("对象转换异常：", e);
        }
    }

}
